package UI;
import Commons.ClientTrasferimentoFileUDP;
import Commons.Indirizzi;
import Commons.TaskDescriptor;
import Commons.Utility;
import Commons.Workflow;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Iterator;



/**Questa è la classe che implementa la comunicazione a basso livello con il WFQueueuManager in modalità UDP PUSH.
 *
 *
 * @author Team5
 */
public class WFQueueManagerProxy_UDP_PUSH extends WFQueueManagerProxy{
    /**
     * Indirizzo del Server WFQueueuManager
     */
     private InetAddress addressDelManager;
    /**
     * Porta del WFQueueManager
     */
    private int portWFinvio;
    private int portWFricezione;

    /**
     * Porta del ServerTarasferimentoUDP
     */
    private int portFile;


    /**Costruttore di default. Associa come predefiniti i seguenti parametri di invio:
     * <ul>
     *      <li><b>address=</b>localhost</li>
     *      <li><b>portWf=</b>12344</li>
     *      <li><b>portFile=</b>12341</li>
     * </ul>
     * @throws UnknownHostException
     */
    public WFQueueManagerProxy_UDP_PUSH() throws UnknownHostException {
        System.out.println("WFQueueManagerProxy_UDP_PUSH(): inizializzo indirizzi e porte");
        addressDelManager=InetAddress.getByName(Indirizzi.indirizzoManager);
        this.portWFinvio = Indirizzi.portaInvioWF;
        this.portWFricezione=Indirizzi.portaRicezioneWF;
        this.portFile = Indirizzi.portaInvioFile;

    }

    /**Costruttore con parametri in ingresso relativi all'indirizzo e le porte del Server WFQueueuManager e ServerTarasferimentoUDP.
     *
     * @param address indirizzo IP Server
     * @param portWf porta WFQueueManager
     * @param portFile porta FileRecieveManager
     */
    public WFQueueManagerProxy_UDP_PUSH(InetAddress address,int portWFinvio,int portWFricezioneint,int portFile) {
        this.addressDelManager=address;
        this.portWFinvio = portWFinvio;
        this.portWFricezione = portWFricezione;
        this.portFile = portFile;
    }


    @Override
     public int enqueue(Workflow wf) throws Exception{

        /**
         * Invia l'intero Workflow al WFQueueManager
         */
        int size=inviaWorkflow(wf);

        /**
         * Analizza il Workflow per verificare la presenza di link a file e procedere all'invio separato degli stessi.
         */
        analizzaWorkflow(wf);
        return size;

     }

     private void analizzaWorkflow(Workflow wf) throws UnknownHostException, SocketException, IOException, FileNotFoundException, InterruptedException
     {
          Iterator<TaskDescriptor> it = wf.getTasks().iterator();
          while(it.hasNext())
          {
              TaskDescriptor td = it.next();
              if(td.getLink()!=null)
              {
                //Bisogna trasferire il file prensente nel path LINK
                  sendFile(td.getLink(),wf.getID(),td.getID());
              }

          }
     }

     private int inviaWorkflow(Workflow wf) throws IOException, ClassNotFoundException, Exception{
          //Serializzare e spedire il Workflow
         Utility u=new Utility();
        try {
            System.out.println("WFQMP: invio WF "+wf.getID());
            u.invioOggettoSerializzatoUDP(wf,this.addressDelManager,this.portWFinvio);
            System.out.println("WFQMP: inizializzo server ricezione");
            u.inizializzaServerRicezioneUDP(this.portWFricezione);
            int size=(Integer) u.riceviOggettoSerializzatoUDP();
            System.out.println("WFQMP: ricevuto int "+size);
            u.chiudiSocket();
            System.out.println("WFQMP: socket chiusa");
            return size;



        } catch (Exception ex) {
                ex.printStackTrace();
            return -1;
        }
            
            



     }

     public void sendFile(String link, Integer wfID, Integer tdID) throws UnknownHostException, SocketException, IOException, FileNotFoundException, InterruptedException
     {

                
                ClientTrasferimentoFileUDP client = new ClientTrasferimentoFileUDP(addressDelManager,portFile,link,link+"-"+wfID.toString()+"-"+tdID.toString());
                client.configuraBuffers(4, 1024);
                client.invioFileRemotoUDP();

     }



    @Override
    public Workflow dequeue() {
       throw new UnsupportedOperationException("Not supported yet.");
    }

}
